package lol.clann.bukkit.pluginboot.config.jackson.location;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lol.clann.bukkit.pluginboot.util.WorldUtils;
import lol.clann.clannboot.annotation.inject.Inject;
import lol.clann.clannboot.annotation.svc.PostInstance;
import lol.clann.clannboot.annotation.svc.Service;
import lol.clann.clannboot.config.jackson.Jackson;
import lol.clann.clannboot.config.jackson.fill.BaseJsonDeserializer;
import org.bukkit.Location;
import org.bukkit.World;

import java.io.IOException;

/**
 * @author pyz
 * @date 2018/10/12 下午10:29
 */
@Service(priority = Integer.MAX_VALUE - 100)
public class LocationRegister {

    @Inject
    private ObjectMapper objectMapper;
    @Inject
    private WorldUtils worldUtils;

    @PostInstance
    private void init() {
        Jackson.addSerializer(Location.class, new JsonSerializer<Location>() {
            @Override
            public void serialize(Location value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                gen.writeStartObject(value);
                gen.writeStringField("world", value.getWorld().getName());
                gen.writeNumberField("x", value.getX());
                gen.writeNumberField("y", value.getY());
                gen.writeNumberField("z", value.getZ());
                gen.writeNumberField("yaw", value.getYaw());
                gen.writeNumberField("pitch", value.getPitch());
                gen.writeEndObject();
            }
        });
        Jackson.addDeserializer(Location.class, new BaseJsonDeserializer<Location>() {
            @Override
            protected Location create(JsonParser p, DeserializationContext context) throws IOException, JsonProcessingException {
                ObjectNode node = objectMapper.readTree(p);
                World world = worldUtils.getWorld(node.get("world").textValue());
                if (world == null) {
                    throw new RuntimeException("反序列化Localtion失败,无效的世界:" + node.get("world").textValue());
                }
                double x = node.get("x").doubleValue();
                double y = node.get("x").doubleValue();
                double z = node.get("x").doubleValue();
                float yaw = node.get("x").floatValue();
                float pitch = node.get("x").floatValue();
                return new Location(world, x, y, z, yaw, pitch);
            }

            @Override
            protected Location fill(Location value, JsonParser p, DeserializationContext context) throws IOException, JsonProcessingException {
                ObjectNode node = objectMapper.readTree(p);
                World world = worldUtils.getWorld(node.get("world").textValue());
                if (world == null) {
                    throw new RuntimeException("反序列化Localtion失败,无效的世界:" + node.get("world").textValue());
                }
                double x = node.get("x").doubleValue();
                double y = node.get("x").doubleValue();
                double z = node.get("x").doubleValue();
                float yaw = node.get("x").floatValue();
                float pitch = node.get("x").floatValue();
                value.setWorld(world);
                value.setX(x);
                value.setY(y);
                value.setZ(z);
                value.setY(yaw);
                value.setPitch(pitch);
                return value;
            }
        });

    }
}
